//引入async模块
const async = require('async')
//引入静态常量模块
const Constant = require('../constant/constant.js')
const sequelize = require('sequelize')
const db = require('../db')

module.exports = {
  autoFn,
  clone,
  checkParams,
  validateLogin,
  validateUserList,
  validateUpdateUserById,
  validateCreateUser,
  validateUpdatePassword,
  validateDeleteUserById,
  validateGetBillList,
  validateUpdateBillById,
  valideGetUserById,
}
function valideGetUserById(params, cb) {
  let { id } = params
  let reg = /^\d+$/
  if (!reg.test(id)) {
    cb({ code: 447, msg: '获得用户的id必须是正整数' })
    return false
  }
  return true
}
//验证账单修改的参数
function validateUpdateBillById(params, cb) {
  let { id, productCount, totalPrice, providerId, isPayment } = params
  //验证账单id
  let reg = /^\d+$/
  if (!reg.test(id)) {
    cb({ code: 440, msg: `要修改的账单id是正整数` })
    return false
  }
  //验证商品供应商id
  if (!reg.test(providerId)) {
    cb({ code: 441, msg: `供应商编号是正整数` })
    return false
  }
  //验证商品是否付款
  reg = /^[12]$/
  if (!reg.test(isPayment)) {
    cb({ code: 442, msg: `isPayment是否付款值是1或2` })
    return false
  }
  //验证商品数量
  reg = /^\d+(\.\d+)?$/
  if (!reg.test(productCount)) {
    cb({ code: 445, msg: `productCount值是正整数或正小数` })
    return false
  }
  //验证商品总价
  if (!reg.test(totalPrice)) {
    cb({ code: 446, msg: `totalPrice值是正整数或正小数` })
    return false
  }
  return true
}

//验证分页请求账单列表的参数
function validateGetBillList(params, cb) {
  let { page, pageSize, providerId, isPayment } = params
  let reg = /^\d+$/
  if (!reg.test(+page)) {
    cb({ code: 436, msg: `页码必须是正整数` })
    return false
  }
  if (!reg.test(+pageSize)) {
    cb({ code: 437, msg: `每页条数必须是正整数` })
    return false
  }
  if (providerId) {
    if (!reg.test(+providerId)) {
      cb({ code: 438, msg: `供应商编号必须是正整数` })
      return false
    }
  }
  if (isPayment) {
    reg = /^[12]$/
    if (!reg.test(isPayment)) {
      cb({ code: 439, msg: `isPayment是否付款值只能是1或2` })
      return false
    }
  }
  return true
}

/**
 * 深度克隆方法
 * @date 2021-03-13
 * @param {any} obj
 * @returns {any}
 */
function clone(obj) {
  return JSON.parse(JSON.stringify(obj))
}

/**
 * 校验参数全局方法，检验params是否有checkArr中的所有参数
 * @date 2021-03-13
 * @param {any} params 请求的参数对象{a:'',b:'',c:''}
 * @param {any} checkArr 需要验证的参数 [a,b] p[a]
 * @param {any} cb 回调函数
 */
function checkParams(params, checkArr, cb) {
  let flag = true
  for (let i = 0; i < checkArr.length; i++) {
    if (!params[checkArr[i]]) {
      flag = false
      break
    }
  }
  if (flag) {
    cb(null)
  } else {
    cb(Constant.LACK)
  }
}

//验证用户名
function validateUsername(params, cb) {
  let { username } = params
  if (!username) {
    cb({ code: 401, msg: '用户名不能为空' })
    return false
  }
  let reg = /^[a-zA-Z\d_]{2,16}$/
  if (!reg.test(username)) {
    cb({ code: 402, msg: '用户名英文、数字、下划线组成2-16位' })
    return false
  }
  return true
}

//验证密码
function validatePassword(params, cb) {
  let { userPassword } = params
  if (!userPassword) {
    cb({ code: 403, msg: '密码不能为空' })
    return false
  }
  if (userPassword.length < 6) {
    cb({ code: 405, msg: '密码最低6位' })
    return false
  }
  return true
}

//验证登录参数
function validateLogin(params, cb) {
  let f1 = validateUsername(params, cb)
  let f2 = validatePassword(params, cb)
  return (f1 & f2) > 0
}

//验证查询用户列表page、pageSize参数
function validateUserList(params, cb) {
  let { page, pageSize } = params
  let reg = /^\d+$/
  if (!reg.test(page)) {
    cb({ code: 406, msg: 'page页码必须是非0整数' })
    return false
  }
  if (!reg.test(pageSize)) {
    cb({ code: 407, msg: 'pageSize条数必须是非0整数' })
    return false
  }
  return true
}

//验证用户修改
function validateUpdateUserById(params, cb) {
  let { userName, gender, birthday, phone, address, userRole, id } = params
  let reg = /^[a-zA-Z\d_]{2,16}$/
  if (!reg.test(userName)) {
    cb({ code: 408, msg: '用户名英文、数字、下划线组成2-16位' })
    return false
  }
  reg = /^[12]$/
  if (!reg.test(gender)) {
    cb({ code: 409, msg: '性别只能是数字1或2' })
    return false
  }
  reg = /^\d{1,4}-(0[1-9]|1[012])-(0[1-9]|[1-2]\d|3[01])(\s{1}([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d))?$/
  if (!reg.test(birthday)) {
    cb({ code: 410, msg: '生日的格式yyyy-mm-dd HH:MM:SS或者yyyy-mm-dd' })
    return false
  }
  let year = +birthday.substring(0, 4)
  let now = new Date()
  if (year > now.getFullYear()) {
    cb({ code: 411, msg: `年的最大值是${now.getFullYear()}` })
    return false
  }
  let month = +birthday.substring(5, 7)
  if (month > 12) {
    cb({ code: 412, msg: `月的最大值是12` })
    return false
  }
  let date = +birthday.substring(8, 10)
  let day = 28
  if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
    day = 29
  }
  let arrMax = [31, day, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  if (date > arrMax[month - 1]) {
    cb({ code: 413, msg: `${month}月的最大日期是${arrMax[month - 1]}` })
    return false
  }
  reg = /^1[3456789]\d{9}?$/
  if (!reg.test(phone)) {
    cb({ code: 414, msg: `电话号码以1开头，第2位是3456789任意1位，共11位` })
    return false
  }
  if (!address) {
    cb({ code: 415, msg: `地址非空` })
    return false
  }
  reg = /^\d+$/
  if (!reg.test(userRole)) {
    cb({ code: 416, msg: `角色值为非空整数` })
    return false
  }
  if (!reg.test(id)) {
    cb({ code: 417, msg: `id值为非空整数` })
    return false
  }
  return true
}

//通用的查询方法
async function select(table, map) {
  let sql = ` SELECT * FROM ${table} WHERE 1 = 1 `
  let arr = []
  for (let key of map.keys()) {
    if (key) {
      sql += ` and ${key} = ? `
      arr.push(map.get(key))
    }
  }
  return await db.query(sql, {
    replacements: arr,
    type: sequelize.QueryTypes.SELECT,
  })
}

//验证用户添加
async function validateCreateUser(params, cb) {
  let {
    userCode,
    userName,
    gender,
    birthday,
    phone,
    userPassword,
    address,
    userRole,
  } = params
  //验证用户编码是否符合要求
  let reg = /^[a-zA-Z\d_]{6,12}$/
  if (!reg.test(userCode)) {
    cb({ code: 418, msg: '用户编码使用英文、数字、下划线组成6-12位' })
    return false
  }
  //验证用户编码是否占用
  let map = new Map()
  map.set('userCode', userCode)
  let res = await select('smbms_user', map)
  if (res.length > 0) {
    cb({ code: 418, msg: `userCode=${userCode}被占用` })
    return false
  }
  //验证用户名
  reg = /^[a-zA-Z\d_]{2,16}$/
  if (!reg.test(userName)) {
    cb({ code: 419, msg: '用户名由英文、数字、下划线组成2-16位' })
    return false
  }
  //验证用户名是否占用
  map = new Map()
  map.set('userName', userName)
  res = await select('smbms_user', map)
  if (res.length > 0) {
    cb({ code: 420, msg: `userName=${userName}被占用` })
    return false
  }
  //验证性别
  reg = /^[12]$/
  if (!reg.test(gender)) {
    cb({ code: 421, msg: '性别只能是数字1或2' })
    return false
  }
  //验证生日
  reg = /^\d{1,4}-(0[1-9]|1[012])-(0[1-9]|[1-2]\d|3[01])(\s{1}([0-1]\d|2[0-3]):([0-5]\d):([0-5]\d))?$/
  if (!reg.test(birthday)) {
    cb({ code: 422, msg: '生日的格式是yyyy-mm-dd HH:MM:SS或者yyyy-mm-dd' })
    return false
  }
  let year = +birthday.substring(0, 4)
  let now = new Date()
  if (year > now.getFullYear()) {
    cb({ code: 423, msg: `生日的年份最大值是${now.getFullYear()}` })
    return false
  }
  let month = +birthday.substring(5, 7)
  if (month > 12) {
    cb({ code: 424, msg: `生日的月份最大值是12` })
    return false
  }
  let date = +birthday.substring(8, 10)
  let day = 28
  if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) {
    day = 29
  }
  let arrMax = [31, day, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
  if (date > arrMax[month - 1]) {
    cb({ code: 425, msg: `${month}月的最大日期是${arrMax[month - 1]}` })
    return false
  }
  //验证电话
  reg = /^1[3456789]\d{9}?$/
  if (!reg.test(phone)) {
    cb({ code: 426, msg: `电话号码以1开头，第2位是3456789任意1位，共11位` })
    return false
  }
  //验证电话是否占用
  map = new Map()
  map.set('phone', phone)
  res = await select('smbms_user', map)
  if (res.length > 0) {
    cb({ code: 427, msg: `phone=${phone}被占用` })
    return false
  }
  if (!address) {
    cb({ code: 428, msg: `地址非空` })
    return false
  }
  //验证角色
  reg = /^\d+$/
  if (!reg.test(userRole)) {
    cb({ code: 429, msg: `角色值为非空整数` })
    return false
  }
  //验证密码
  reg = /^[a-zA-Z\d_$()-+*&{}@!%]{6,12}$/
  if (!reg.test(userPassword)) {
    cb({ code: 430, msg: '密码由英文、数字、下划线组成6-12位' })
    return false
  }
  let str = '_$()-+*&{}@!%'
  //判断特殊字符,false表示没有特殊字符
  let flag = false
  for (let i = 0; i < str.length; i++) {
    let code = str[i]
    if (userPassword.indexOf(code) !== -1) {
      flag = true
      break
    }
  }
  if (!flag) {
    cb({ code: 431, msg: '密码必须包含_$()-+*&{}@!%r任意字符' })
    return false
  }
  return true
}

//验证密码修改参数
function validateUpdatePassword(params, cb) {
  let { userPassword, id } = params
  //验证密码
  let reg = /^[a-zA-Z\d_$()-+*&{}@!%]{6,12}$/
  if (!reg.test(userPassword)) {
    cb({ code: 432, msg: '密码由英文、数字、下划线组成6-12位' })
    return false
  }
  let str = '_$()-+*&{}@!%'
  //判断特殊字符,false表示没有特殊字符
  let flag = false
  for (let i = 0; i < str.length; i++) {
    let code = str[i]
    if (userPassword.indexOf(code) !== -1) {
      flag = true
      break
    }
  }
  if (!flag) {
    cb({ code: 433, msg: '密码必须包含_$()-+*&{}@!%r任意字符' })
    return false
  }
  reg = /^\d+$/
  if (!reg.test(id)) {
    cb({ code: 434, msg: '用户id是整数' })
    return false
  }
  return true
}

//验证删除用户的id参数
function validateDeleteUserById(params, cb) {
  let { id } = params
  let reg = /^\d+$/
  if (!reg.test(id)) {
    cb({ code: 435, msg: '用户的id必须是正整数' })
    return false
  }
  return true
}

/**
 * 返回统一的方法，返回json数据
 * @date 2021-03-13
 * @param {any} tasks
 * @param {any} res
 * @param {any} resObj
 * @returns {any}
 */
function autoFn(tasks, res, resObj) {
  async.auto(tasks, async function (err) {
    if (err) {
      //cb(msg) msg===err,err是执行回调函数的参数
      console.log(JSON.stringify(err))
      res.send({
        code: err.code || Constant.DEFAULT_ERROR.code,
        msg: err.msg || JSON.stringify(err),
      })
    } else {
      console.log(resObj)
      res.send(resObj)
    }
  })
}
